require 'page_controller'
require 'account/account.rb'
require 'task_list/task_list_manager'


# === ToDo Dash 用のパスマップ
#
# Author:: krdlab
#
class TddPathMapper < PathMapper
protected
  def create_map
    return {
      "login"          => "view/login.rhtml",
      "create_account" => "view/create_account.rhtml",
      "logout"         => "view/logout.rhtml",
      "main"           => "view/main.rhtml"
    }
  end
end

# === ToDo Dash 用のページコントローラ
#
# Author:: krdlab
#
class TddPageController < PageController

  def initialize
    super
    @logger.progname = "Todo Dash"
  end

  def get_path4log
    return '/var/log/todo_dash/todo_dash.log'
  end

  def create_mapper
    return TddPathMapper.new
  end

  def create_view_action(action, request)
    return ViewAction.new(@mapper.to_path(action), request)
  end

public

  LOGIN_ID  = 'login-id'

  LOGIN_PW  = 'login-password'

  LOGIN_PW2 = 'login-password2'

  def login(request)
    request.add_attr(:login_failed)
    request.login_failed = false

    if not request.is_post? then
      logger.debug { "login, path=#{@mapper.to_path('login')}" }
      return create_view_action('login', request)
    end

    if request.session.nil? then
      # 通常のログイン
      id = request.get_parameter(LOGIN_ID)
      pw = request.get_parameter(LOGIN_PW)
      ac = Account.login(id, pw)
      if ac.nil? then
        # 通常のログインに失敗
        request.login_failed = true
        return create_view_action('login', request)
      else
        # ログインに成功
        request.new_session
        prepare_account(ac, request)
        return redirect_to(request)
      end
    else
      # チケットを照合
      ac = Account.find_by_ticket(request.session['ticket'])
      if ac.nil? then
        # 無効なチケット
        # 普通にログイン画面を出せばよい
        return create_view_action('login', request)
      else
        # ログイン状態と判定
        request.session.delete
        request.new_session
        prepare_account(ac, request)
        return redirect_to(request)
      end
    end
  end

  def set_new_ticket(ac, request)
    new_ticket = Account.create_ticket
    ac.ticket = new_ticket
    ac.save
    request.session['ticket'] = new_ticket
  end

  def prepare_account(ac, request)
    set_new_ticket(ac, request)
    if request.action == 'login' then
      request.action = 'main'
    end
  end

  def create_account(request)
    request.add_attr(:invalid_id)
    request.invalid_id = false
    request.add_attr(:invalid_passwords)
    request.invalid_passwords = false

    if not request.is_post? then
      return create_view_action('create_account', request)
    end
    if not check_put_passwords(request) then
      request.invalid_passwords = true
      return create_view_action('create_account', request)
    end

    id = request.get_parameter(LOGIN_ID)
    pw = request.get_parameter(LOGIN_PW)
    ac = Account.find_by_name(id)
    if not ac.nil? then
      request.invalid_id = true
      return create_view_action('create_account', request)
    end

    ac = Account.new_account(id, pw)
    set_new_ticket(ac, request)
    request.action = 'login'
    loggger.debug { "login succeeded, id=#{id}" }
    return create_view_action(request.action, request)
  end

  def check_put_passwords(request)
    pw1 = request.get_parameter(LOGIN_PW)
    pw2 = request.get_parameter(LOGIN_PW2)
    if pw1.blank? or pw2.blank? then
      return false
    end
    return pw1 == pw2
  end

  def logout(request)
    ticket = request.session['ticket']
    ac = Account.find_by_ticket(ticket)
    if not ac.nil? then
      ac.logout
      request.session['ticket'] = nil
    end
  end

  def main(request)
  end

  def add_task(request)
    ac = Account.find_by_ticket(request.session['ticket'])
    if ac.nil? then
      return redirect_to('login', request)
    end
    t = Tack.new(:user_id => ac.id,
                  :priority => 1,
                  :done => false,
                  :title => 'Edit This')
    TaskListManager.new.add(t)
    return redirect_to('main', request)
  end

  def update_task(request)
    ac = Account.find_by_ticket(request.session['ticket'])
    if ac.nil? then
      return redirect_to('login', request)
    end
    tid = request.get_parameter('task_id')
    if not tid.blank? then
      done = request.get_parameter('done')
      title = request.get_parameter('title')
      do_update_task(:id => tid, :done => done, :title => title)
    end
    return redirect_to('main', request)
  end

  def do_update_task(args)
    tlm = TaskListManager.new
    task = tlm.search(:conditions => ["id = ?", args['id']])
    if task.nil? then
      return;
    end
    task.done = args['done'] == 'on'
    task.title = args['title']
    tlm.modify(task)
  end

  def remove_task(request)
    ac = Account.find_by_ticket(request.session['ticket'])
    if ac.nil? then
      return redirect_to('login', request)
    end
    tid = request.get_parameter('task_id')
    TaskListManager.new.remove(tid) if tid
    return redirect_to('main', request)
  end
end

